Overlays are drawings that get rendered on top of the inspected window.
The only overlay in existence so far is the highlight overlay, which is
used to highlight widgets and replaces the "draw" signal handler used
previously.
--- /dev/null
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "highlightoverlay.h"
+
+#include "gtkintl.h"
+#include "gtkwidget.h"
+
+struct _GtkHighlightOverlay
+{
+ GtkInspectorOverlay parent_instance;
+
+ GtkWidget *widget;
+ GdkRGBA color;
+};
+
+struct _GtkHighlightOverlayClass
+{
+ GtkInspectorOverlayClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkHighlightOverlay, gtk_highlight_overlay, GTK_TYPE_INSPECTOR_OVERLAY)
+
+static void
+gtk_highlight_overlay_snapshot (GtkInspectorOverlay *overlay,
+ GtkSnapshot *snapshot,
+ GtkWidget *widget)
+{
+ GtkHighlightOverlay *self = GTK_HIGHLIGHT_OVERLAY (overlay);
+ graphene_rect_t bounds;
+
+ if (!gtk_widget_compute_bounds (self->widget, widget, &bounds))
+ return;
+
+ gtk_snapshot_append_color (snapshot,
+ &self->color,
+ &bounds,
+ "InspectorHighlight");
+}
+
+static void
+gtk_highlight_overlay_queue_draw (GtkInspectorOverlay *overlay)
+{
+ GtkHighlightOverlay *self = GTK_HIGHLIGHT_OVERLAY (overlay);
+
+ gtk_widget_queue_draw (self->widget);
+}
+
+static void
+gtk_highlight_overlay_dispose (GObject *object)
+{
+ GtkHighlightOverlay *self = GTK_HIGHLIGHT_OVERLAY (object);
+
+ g_clear_object (&self->widget);
+
+ G_OBJECT_CLASS (gtk_highlight_overlay_parent_class)->dispose (object);
+}
+
+static void
+gtk_highlight_overlay_class_init (GtkHighlightOverlayClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkInspectorOverlayClass *overlay_class = GTK_INSPECTOR_OVERLAY_CLASS (klass);
+
+ overlay_class->snapshot = gtk_highlight_overlay_snapshot;
+ overlay_class->queue_draw = gtk_highlight_overlay_queue_draw;
+
+ gobject_class->dispose = gtk_highlight_overlay_dispose;
+}
+
+static void
+gtk_highlight_overlay_init (GtkHighlightOverlay *self)
+{
+ self->color = (GdkRGBA) { 0.0, 0.0, 1.0, 0.2 };
+}
+
+GtkInspectorOverlay *
+gtk_highlight_overlay_new (GtkWidget *widget)
+{
+ GtkHighlightOverlay *self;
+
+ self = g_object_new (GTK_TYPE_HIGHLIGHT_OVERLAY, NULL);
+
+ self->widget = g_object_ref (widget);
+
+ return GTK_INSPECTOR_OVERLAY (self);
+}
+
+GtkWidget *
+gtk_highlight_overlay_get_widget (GtkHighlightOverlay *self)
+{
+ return self->widget;
+}
+
+void
+gtk_highlight_overlay_set_color (GtkHighlightOverlay *self,
+ const GdkRGBA *color)
+{
+ if (gdk_rgba_equal (&self->color, color))
+ return;
+
+ self->color = *color;
+ gtk_inspector_overlay_queue_draw (GTK_INSPECTOR_OVERLAY (self));
+}
--- /dev/null
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_HIGHLIGHT_OVERLAY_H__
+#define __GTK_HIGHLIGHT_OVERLAY_H__
+
+#include "inspectoroverlay.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_HIGHLIGHT_OVERLAY (gtk_highlight_overlay_get_type ())
+G_DECLARE_FINAL_TYPE (GtkHighlightOverlay, gtk_highlight_overlay, GTK, HIGHLIGHT_OVERLAY, GtkInspectorOverlay)
+
+GtkInspectorOverlay * gtk_highlight_overlay_new (GtkWidget *widget);
+
+GtkWidget * gtk_highlight_overlay_get_widget (GtkHighlightOverlay *self);
+void gtk_highlight_overlay_set_color (GtkHighlightOverlay *self,
+ const GdkRGBA *color);
+
+G_END_DECLS
+
+#endif /* __GTK_HIGHLIGHT_OVERLAY_H__ */
#include <glib/gi18n-lib.h>
#include "window.h"
+
+#include "highlightoverlay.h"
#include "object-tree.h"
#include "gtkstack.h"
return widget;
}
-static gboolean draw_flash (GtkWidget *widget,
- cairo_t *cr,
- GtkInspectorWindow *iw);
-
static void
clear_flash (GtkInspectorWindow *iw)
{
- if (iw->flash_widget)
+ if (iw->flash_overlay)
{
- gtk_widget_queue_draw (iw->flash_widget);
- g_signal_handlers_disconnect_by_func (iw->flash_widget, draw_flash, iw);
- g_signal_handlers_disconnect_by_func (iw->flash_widget, clear_flash, iw);
- iw->flash_widget = NULL;
+ gtk_inspector_window_remove_overlay (iw, iw->flash_overlay);
+ g_clear_object (&iw->flash_overlay);
}
}
clear_flash (iw);
iw->flash_count = 1;
- iw->flash_widget = widget;
- g_signal_connect_after (widget, "draw", G_CALLBACK (draw_flash), iw);
- g_signal_connect_swapped (widget, "unmap", G_CALLBACK (clear_flash), iw);
- gtk_widget_queue_draw (widget);
+ iw->flash_overlay = gtk_highlight_overlay_new (widget);
+ gtk_inspector_window_add_overlay (iw, iw->flash_overlay);
}
static void
return;
}
- if (iw->flash_widget == widget)
+ if (iw->flash_overlay &&
+ gtk_highlight_overlay_get_widget (GTK_HIGHLIGHT_OVERLAY (iw->flash_overlay)) == widget)
{
/* Already selected */
return;
deemphasize_window (GTK_WIDGET (iw));
}
-static gboolean
-draw_flash (GtkWidget *widget,
- cairo_t *cr,
- GtkInspectorWindow *iw)
-{
- GtkAllocation alloc;
-
- if (iw && iw->flash_count % 2 == 0)
- return FALSE;
-
- if (GTK_IS_WINDOW (widget))
- {
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
- /* We don't want to draw the drag highlight around the
- * CSD window decorations
- */
- if (child == NULL)
- return FALSE;
-
- gtk_widget_get_allocation (child, &alloc);
- }
- else
- {
- alloc.x = 0;
- alloc.y = 0;
- alloc.width = gtk_widget_get_allocated_width (widget);
- alloc.height = gtk_widget_get_allocated_height (widget);
- }
-
- cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.2);
- cairo_rectangle (cr,
- alloc.x + 0.5, alloc.y + 0.5,
- alloc.width - 1, alloc.height - 1);
- cairo_fill (cr);
-
- return FALSE;
-}
-
static gboolean
on_flash_timeout (GtkInspectorWindow *iw)
{
- gtk_widget_queue_draw (iw->flash_widget);
-
iw->flash_count++;
+ gtk_highlight_overlay_set_color (GTK_HIGHLIGHT_OVERLAY (iw->flash_overlay),
+ &(GdkRGBA) {
+ 0.0, 0.0, 1.0,
+ (iw && iw->flash_count % 2 == 0) ? 0.0 : 0.2
+ });
+
if (iw->flash_count == 6)
{
- g_signal_handlers_disconnect_by_func (iw->flash_widget, draw_flash, iw);
- g_signal_handlers_disconnect_by_func (iw->flash_widget, clear_flash, iw);
- iw->flash_widget = NULL;
+ clear_flash (iw);
iw->flash_cnx = 0;
return G_SOURCE_REMOVE;
iw->flash_cnx = g_timeout_add (150, (GSourceFunc) on_flash_timeout, iw);
}
-void
-gtk_inspector_start_highlight (GtkWidget *widget)
-{
- g_signal_connect_after (widget, "draw", G_CALLBACK (draw_flash), NULL);
- gtk_widget_queue_draw (widget);
-}
-
-void
-gtk_inspector_stop_highlight (GtkWidget *widget)
-{
- g_signal_handlers_disconnect_by_func (widget, draw_flash, NULL);
- g_signal_handlers_disconnect_by_func (widget, clear_flash, NULL);
- gtk_widget_queue_draw (widget);
-}
-
void
gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow *iw)
{
--- /dev/null
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "inspectoroverlay.h"
+
+#include "gtkintl.h"
+
+typedef struct _GtkInspectorOverlayPrivate GtkInspectorOverlayPrivate;
+
+struct _GtkInspectorOverlayPrivate
+{
+};
+
+G_DEFINE_ABSTRACT_TYPE (GtkInspectorOverlay, gtk_inspector_overlay, G_TYPE_OBJECT)
+
+static void
+gtk_inspector_overlay_default_snapshot (GtkInspectorOverlay *self,
+ GtkSnapshot *snapshot,
+ GtkWidget *widget)
+{
+}
+
+static void
+gtk_inspector_overlay_default_queue_draw (GtkInspectorOverlay *self)
+{
+}
+
+static void
+gtk_inspector_overlay_class_init (GtkInspectorOverlayClass *class)
+{
+ class->snapshot = gtk_inspector_overlay_default_snapshot;
+ class->queue_draw = gtk_inspector_overlay_default_queue_draw;
+}
+
+static void
+gtk_inspector_overlay_init (GtkInspectorOverlay *self)
+{
+}
+
+void
+gtk_inspector_overlay_snapshot (GtkInspectorOverlay *self,
+ GtkSnapshot *snapshot,
+ GtkWidget *widget)
+{
+ GTK_INSPECTOR_OVERLAY_GET_CLASS (self)->snapshot (self, snapshot, widget);
+}
+
+void
+gtk_inspector_overlay_queue_draw (GtkInspectorOverlay *self)
+{
+ GTK_INSPECTOR_OVERLAY_GET_CLASS (self)->queue_draw (self);
+}
+
--- /dev/null
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_INSPECTOR_OVERLAY_H__
+#define __GTK_INSPECTOR_OVERLAY_H__
+
+#include <gtk/gtksnapshot.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_INSPECTOR_OVERLAY (gtk_inspector_overlay_get_type ())
+
+G_DECLARE_DERIVABLE_TYPE (GtkInspectorOverlay, gtk_inspector_overlay, GTK, INSPECTOR_OVERLAY, GObject)
+
+struct _GtkInspectorOverlayClass
+{
+ GObjectClass parent_class;
+
+ void (* snapshot) (GtkInspectorOverlay *self,
+ GtkSnapshot *snapshot,
+ GtkWidget *widget);
+ void (* queue_draw) (GtkInspectorOverlay *self);
+};
+
+void gtk_inspector_overlay_snapshot (GtkInspectorOverlay *self,
+ GtkSnapshot *snapshot,
+ GtkWidget *widget);
+void gtk_inspector_overlay_queue_draw (GtkInspectorOverlay *self);
+
+G_END_DECLS
+
+#endif /* __GTK_INSPECTOR_OVERLAY_H__ */
'gtkstackcombo.c',
'gtktreemodelcssnode.c',
'gtktreemodelrendernode.c',
+ 'highlightoverlay.c',
'init.c',
'inspect-button.c',
+ 'inspectoroverlay.c',
'logs.c',
'magnifier.c',
'menu.c',
#include <glib/gi18n-lib.h>
#include "size-groups.h"
+
+#include "highlightoverlay.h"
#include "window.h"
#include "gtkcomboboxtext.h"
typedef struct {
GtkListBoxRow parent;
+ GtkInspectorOverlay *highlight;
GtkWidget *widget;
} SizeGroupRow;
state = gtk_widget_get_state_flags (widget);
if ((state & GTK_STATE_FLAG_PRELIGHT) != (old_state & GTK_STATE_FLAG_PRELIGHT))
{
+ GtkInspectorWindow *iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_toplevel (widget));
+
if (state & GTK_STATE_FLAG_PRELIGHT)
- gtk_inspector_start_highlight (row->widget);
+ {
+ row->highlight = gtk_highlight_overlay_new (row->widget);
+ gtk_inspector_window_add_overlay (iw, row->highlight);
+ }
else
- gtk_inspector_stop_highlight (row->widget);
+ {
+ gtk_inspector_window_remove_overlay (iw, row->highlight);
+ g_clear_object (&row->highlight);
+ }
}
}
NULL));
}
+void
+gtk_inspector_window_add_overlay (GtkInspectorWindow *iw,
+ GtkInspectorOverlay *overlay)
+{
+ iw->overlays = g_list_prepend (iw->overlays, g_object_ref (overlay));
+
+ gtk_inspector_overlay_queue_draw (overlay);
+}
+
+void
+gtk_inspector_window_remove_overlay (GtkInspectorWindow *iw,
+ GtkInspectorOverlay *overlay)
+{
+ GList *item;
+
+ item = g_list_find (iw->overlays, overlay);
+ if (item == NULL)
+ return;
+
+ gtk_inspector_overlay_queue_draw (overlay);
+
+ iw->overlays = g_list_delete_link (iw->overlays, item);
+}
+
void
gtk_inspector_window_rescan (GtkWidget *widget)
{
region,
node);
+ if (iw->overlays)
+ {
+ GtkSnapshot *snapshot;
+ GList *l;
+
+ snapshot = gtk_snapshot_new (FALSE, "Inspector Overlay");
+ gtk_snapshot_append_node (snapshot, node);
+
+ for (l = iw->overlays; l; l = l->next)
+ {
+ gtk_inspector_overlay_snapshot (l->data, snapshot, widget);
+ }
+
+ gsk_render_node_unref (node);
+ node = gtk_snapshot_free_to_node (snapshot);
+ }
+
return node;
}
#include <gtk/gtkwindow.h>
+#include "inspectoroverlay.h"
+
#define GTK_TYPE_INSPECTOR_WINDOW (gtk_inspector_window_get_type())
#define GTK_INSPECTOR_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_WINDOW, GtkInspectorWindow))
#define GTK_INSPECTOR_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_WINDOW, GtkInspectorWindowClass))
GtkWidget *invisible;
GtkWidget *selected_widget;
- GtkWidget *flash_widget;
GList *extra_pages;
gboolean grabbed;
+ GtkInspectorOverlay *flash_overlay;
gint flash_count;
gint flash_cnx;
+ GList *overlays;
+
} GtkInspectorWindow;
typedef struct
void gtk_inspector_flash_widget (GtkInspectorWindow *iw,
GtkWidget *widget);
-void gtk_inspector_start_highlight (GtkWidget *widget);
-void gtk_inspector_stop_highlight (GtkWidget *widget);
void gtk_inspector_on_inspect (GtkWidget *widget,
GtkInspectorWindow *iw);
+void gtk_inspector_window_add_overlay (GtkInspectorWindow *iw,
+ GtkInspectorOverlay *overlay);
+void gtk_inspector_window_remove_overlay (GtkInspectorWindow *iw,
+ GtkInspectorOverlay *overlay);
+
void gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow *iw);
void gtk_inspector_window_rescan (GtkWidget *iw);